package nuc.ss.novel.utils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author : zzr
 * @description :这是一个字符串处理工具的方法
 * 例如判断字符串是否为空，下划线，命名转换等等 在对用户输入进行验证处理的时候使用
 * @date :
 */
public class StringUtils {
    /**
     * public static Pattern compile(String regex)将给定的正则表达式编译为模式。
     * 参数
     * regex - 要编译的表达式
     * 结果
     * 给定的正则表达式编译成一个模式
     */
    //linePattern 和 humPattern两个静态方法用于正则表达式模式
    // linePattern匹配下划线后面跟着的一个单词字符，以便lineToHump方法进行下划线转驼峰的操作
    // humPattern匹配大写字母，在humToLine方法中用于驼峰转变下划线的操作
    // 匹配_后面的单词字符 - 匹配器
    private static Pattern linePattern = Pattern.compile("_(\\w)");
    //_表示匹配下划线字符，(\\w)是一个捕获组，用于匹配一个单词字符
    //使用示例：
    //假设输入字符串为user_name -- 使用linePattern方法进行匹配，匹配到_n的时候，捕获到n，通过toUpperCase()方法，将其转换为大写N 实现驼峰

    //匹配大写字母后 - 匹配器
    private static Pattern humPattern = Pattern.compile("[A-Z]");
    //使用示例：
    //假设输入字符串userName，使用humPattern匹配，匹配到N(大写字母)之后，appendReplacement方法将其转换为_n，最终实现将驼峰转换为下划线user_name

    //空值检查方法
    public static boolean isEmpty(String str) {
        if ("".equals(str) || str == null) { //注意这里使用 || 只要是""或者null一个 就返回是空值true
            return true; //字符串为空或者null 返回true
        } else {
            return false;
        }
    }

    //不为空检查方法
    public static boolean isNotEmpty(String str) {
        if (!"".equals(str) && str != null) { //注意这里使用的是&&与 str ！"" 和 != null 任意一个条件都不满足 都无法返回true(不是空值)
            return true;
        } else {
            return false;
        }
    }

    // 下划线转驼峰方法
    public static String linToHump(String str) {
        str.toLowerCase(); //先将字符串转为小写 方便统一处理
        Matcher matcher = linePattern.matcher(str); //使用linePattern创建的匹配器对传入的str字符串进行匹配
        //当找到匹配项(下划线后面跟着一个单词字符) 获取 并将匹配到的单词字符传唤为大写字母
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            //appendReplacement 将给定的替换字符串(matcher.group(1))附加到字符串缓冲区(sb)
            matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
        }
        //appendTail方法的作用是处理那些未被匹配的剩余部分。
        /**
         * 示例：
         * hello_world --> while循环结束之后 会处理_w的匹配，将w小写替换成W大写，matcher.appendTail(sb)会将剩下的orld字符添加到sb中
         * 使得return sb.toString()的结果为helloWorld
         */
        matcher.appendTail(sb);
        return sb.toString();
    }

    // 驼峰转下划线方法
    //1.
    public static String humToLine(String str) {
        return str.replaceAll("[A-Z]", "_$0").toLowerCase();
        //利用replaceAll方法，将字符串中的所有大写字母，替换成下划线加上大写字母的小写形式，然后再把整个字符串转换为小写字母
    }

    //2. 不同与1全部的转换
    // 使用humPattern创建的匹配器进行匹配，从匹配到大写字母的时候，将其替换为下划线加上大写字母的小写形式，appendTail追加剩余的字符
    //StringBuffer转换为字符串返回
    //2方法相对1的情况效率更高，可以更惊喜地控制替换过程
    public static String humToLine2(String str) {
        Matcher matcher = humPattern.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    //中文字符转Unicode编码方法
    //与数据库进行交互时，有时候会出现数据库的字符编码的设置不匹配导致中文字符出现乱码
    //使用该方法解决
    public static String chinaToUnicode(String str) {
        String result = ""; //存储转换后的结果
        for (int i = 0; i < str.length(); i++) {
            int chr1 = (char) str.charAt(i); // 向上转型 char 2 个字节 转为 int 4 个字节 转为int类型后 得到字符的Unicode编码
            if (chr1 >= 19968 && chr1 <= 171941) { // chr1是否在汉字的Unicode范围内 \u4e00 -- \u9fa5（中文）
                result += "\\u" + Integer.toHexString(chr1);//将Unicode编码值转换为十六进制字符串形式 然后在前面加上 \\u 添加到result字符串中
            } else {
                //不是汉字，再将其添加到字符串result中
                result += str.charAt(i);
            }
        }
        return result;
    }


}
